home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / dev / lang / Python16_Src.lha / Python16_Source / Objects / methodobject.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-10  |  5.0 KB  |  263 lines

  1. /* Method object implementation */
  2.  
  3. #include "Python.h"
  4.  
  5. #include "token.h"
  6. #include "protos/methodobject.h"
  7.  
  8. static PyCFunctionObject *free_list = NULL;
  9.  
  10. PyObject *
  11. PyCFunction_New(ml, self)
  12.     PyMethodDef *ml;
  13.     PyObject *self;
  14. {
  15.     PyCFunctionObject *op;
  16.     op = free_list;
  17.     if (op != NULL) {
  18.         free_list = (PyCFunctionObject *)(op->m_self);
  19.         PyObject_INIT(op, &PyCFunction_Type);
  20.     }
  21.     else {
  22.         op = PyObject_NEW(PyCFunctionObject, &PyCFunction_Type);
  23.         if (op == NULL)
  24.             return NULL;
  25.     }
  26.     op->m_ml = ml;
  27.     Py_XINCREF(self);
  28.     op->m_self = self;
  29.     return (PyObject *)op;
  30. }
  31.  
  32. PyCFunction
  33. PyCFunction_GetFunction(op)
  34.     PyObject *op;
  35. {
  36.     if (!PyCFunction_Check(op)) {
  37.         PyErr_BadInternalCall();
  38.         return NULL;
  39.     }
  40.     return ((PyCFunctionObject *)op) -> m_ml -> ml_meth;
  41. }
  42.  
  43. PyObject *
  44. PyCFunction_GetSelf(op)
  45.     PyObject *op;
  46. {
  47.     if (!PyCFunction_Check(op)) {
  48.         PyErr_BadInternalCall();
  49.         return NULL;
  50.     }
  51.     return ((PyCFunctionObject *)op) -> m_self;
  52. }
  53.  
  54. int
  55. PyCFunction_GetFlags(op)
  56.     PyObject *op;
  57. {
  58.     if (!PyCFunction_Check(op)) {
  59.         PyErr_BadInternalCall();
  60.         return -1;
  61.     }
  62.     return ((PyCFunctionObject *)op) -> m_ml -> ml_flags;
  63. }
  64.  
  65. /* Methods (the standard built-in methods, that is) */
  66.  
  67. static void
  68. meth_dealloc(m)
  69.     PyCFunctionObject *m;
  70. {
  71.     Py_XDECREF(m->m_self);
  72.     m->m_self = (PyObject *)free_list;
  73.     free_list = m;
  74. }
  75.  
  76. static PyObject *
  77. meth_getattr(m, name)
  78.     PyCFunctionObject *m;
  79.     char *name;
  80. {
  81.     if (strcmp(name, "__name__") == 0) {
  82.         return PyString_FromString(m->m_ml->ml_name);
  83.     }
  84.     if (strcmp(name, "__doc__") == 0) {
  85.         char *doc = m->m_ml->ml_doc;
  86.         if (doc != NULL)
  87.             return PyString_FromString(doc);
  88.         Py_INCREF(Py_None);
  89.         return Py_None;
  90.     }
  91.     if (strcmp(name, "__self__") == 0) {
  92.         PyObject *self;
  93.         if (PyEval_GetRestricted()) {
  94.             PyErr_SetString(PyExc_RuntimeError,
  95.              "method.__self__ not accessible in restricted mode");
  96.             return NULL;
  97.         }
  98.         self = m->m_self;
  99.         if (self == NULL)
  100.             self = Py_None;
  101.         Py_INCREF(self);
  102.         return self;
  103.     }
  104.     if (strcmp(name, "__members__") == 0) {
  105.         return Py_BuildValue("[sss]",
  106.                      "__doc__", "__name__", "__self__");
  107.     }
  108.     PyErr_SetString(PyExc_AttributeError, name);
  109.     return NULL;
  110. }
  111.  
  112. static PyObject *
  113. meth_repr(m)
  114.     PyCFunctionObject *m;
  115. {
  116.     char buf[200];
  117.     if (m->m_self == NULL)
  118.         sprintf(buf, "<built-in function %.80s>", m->m_ml->ml_name);
  119.     else
  120.         sprintf(buf,
  121.             "<built-in method %.80s of %.80s object at %lx>",
  122.             m->m_ml->ml_name, m->m_self->ob_type->tp_name,
  123.             (long)m->m_self);
  124.     return PyString_FromString(buf);
  125. }
  126.  
  127. static int
  128. meth_compare(a, b)
  129.     PyCFunctionObject *a, *b;
  130. {
  131.     if (a->m_self != b->m_self)
  132.         return (a->m_self < b->m_self) ? -1 : 1;
  133.     if (a->m_ml->ml_meth == b->m_ml->ml_meth)
  134.         return 0;
  135.     if (strcmp(a->m_ml->ml_name, b->m_ml->ml_name) < 0)
  136.         return -1;
  137.     else
  138.         return 1;
  139. }
  140.  
  141. static long
  142. meth_hash(a)
  143.     PyCFunctionObject *a;
  144. {
  145.     long x;
  146.     if (a->m_self == NULL)
  147.         x = 0;
  148.     else {
  149.         x = PyObject_Hash(a->m_self);
  150.         if (x == -1)
  151.             return -1;
  152.     }
  153.     return x ^ (long) a->m_ml->ml_meth;
  154. }
  155.  
  156. PyTypeObject PyCFunction_Type = {
  157.     PyObject_HEAD_INIT(&PyType_Type)
  158.     0,
  159.     "builtin_function_or_method",
  160.     sizeof(PyCFunctionObject),
  161.     0,
  162.     (destructor)meth_dealloc, /*tp_dealloc*/
  163.     0,        /*tp_print*/
  164.     (getattrfunc)meth_getattr, /*tp_getattr*/
  165.     0,        /*tp_setattr*/
  166.     (cmpfunc)meth_compare, /*tp_compare*/
  167.     (reprfunc)meth_repr, /*tp_repr*/
  168.     0,        /*tp_as_number*/
  169.     0,        /*tp_as_sequence*/
  170.     0,        /*tp_as_mapping*/
  171.     (hashfunc)meth_hash, /*tp_hash*/
  172. };
  173.  
  174. /* List all methods in a chain -- helper for findmethodinchain */
  175.  
  176. static PyObject *
  177. listmethodchain(chain)
  178.     PyMethodChain *chain;
  179. {
  180.     PyMethodChain *c;
  181.     PyMethodDef *ml;
  182.     int i, n;
  183.     PyObject *v;
  184.     
  185.     n = 0;
  186.     for (c = chain; c != NULL; c = c->link) {
  187.         for (ml = c->methods; ml->ml_name != NULL; ml++)
  188.             n++;
  189.     }
  190.     v = PyList_New(n);
  191.     if (v == NULL)
  192.         return NULL;
  193.     i = 0;
  194.     for (c = chain; c != NULL; c = c->link) {
  195.         for (ml = c->methods; ml->ml_name != NULL; ml++) {
  196.             PyList_SetItem(v, i, PyString_FromString(ml->ml_name));
  197.             i++;
  198.         }
  199.     }
  200.     if (PyErr_Occurred()) {
  201.         Py_DECREF(v);
  202.         return NULL;
  203.     }
  204.     PyList_Sort(v);
  205.     return v;
  206. }
  207.  
  208. /* Find a method in a method chain */
  209.  
  210. PyObject *
  211. Py_FindMethodInChain(chain, self, name)
  212.     PyMethodChain *chain;
  213.     PyObject *self;
  214.     char *name;
  215. {
  216.     if (name[0] == '_' && name[1] == '_') {
  217.         if (strcmp(name, "__methods__") == 0)
  218.             return listmethodchain(chain);
  219.         if (strcmp(name, "__doc__") == 0) {
  220.             char *doc = self->ob_type->tp_doc;
  221.             if (doc != NULL)
  222.                 return PyString_FromString(doc);
  223.         }
  224.     }
  225.     while (chain != NULL) {
  226.         PyMethodDef *ml = chain->methods;
  227.         for (; ml->ml_name != NULL; ml++) {
  228.             if (name[0] == ml->ml_name[0] &&
  229.                 strcmp(name+1, ml->ml_name+1) == 0)
  230.                 return PyCFunction_New(ml, self);
  231.         }
  232.         chain = chain->link;
  233.     }
  234.     PyErr_SetString(PyExc_AttributeError, name);
  235.     return NULL;
  236. }
  237.  
  238. /* Find a method in a single method list */
  239.  
  240. PyObject *
  241. Py_FindMethod(methods, self, name)
  242.     PyMethodDef *methods;
  243.     PyObject *self;
  244.     char *name;
  245. {
  246.     PyMethodChain chain;
  247.     chain.methods = methods;
  248.     chain.link = NULL;
  249.     return Py_FindMethodInChain(&chain, self, name);
  250. }
  251.  
  252. /* Clear out the free list */
  253.  
  254. void
  255. PyCFunction_Fini()
  256. {
  257.     while (free_list) {
  258.         PyCFunctionObject *v = free_list;
  259.         free_list = (PyCFunctionObject *)(v->m_self);
  260.         PyObject_DEL(v);
  261.     }
  262. }
  263.